#Inputs:
#  vtopIn: the input virtual topology
#  targetSize: the number of nodes in output virtual topology
#  vtopOrig: the original virtual topology, used for reference only
#  log: storing useful info passing around programs, e.g., path to output xml
#  nodeType: the node type being processed
#  partitionID: the network partition being processed

#Definitions:
#  vtopPart = nodes of nodeType & in partitionID plus nodes and links connected
#  node.neighbors = all qualified neighors of the node
#  node.FI = the fidelity index of the node
#  node.REQ = the requirements for any resourses(CPU, RAM, HDD etc.)
#  node.INT = the interfaces number of the node
#  node.mapInfo = nodes that are merged to the current node, self if not merged
#  link.endNodes = two endNodes of the link
#  link.BW = the bandwidth requirement of the link
#  link.delay = the delay requirement of the links
#  link.mapInfo = links that are merged to the current link, self if not merged

while nodeNumber > targetSize:
    N1 = node[min(FI)]
    N2 = N1.neighbors[min(FI)]
    while 1:
          if N1.INT + N2.INT - 2 or any N1.REQ + N2.REQ > MAXIMUM:
                remove N2 from N1.neighbors
                N2 = N1.neighbors[min(FI)]
          else:
                break
    new_node.FI/REQ/mapInfo = N1.FI/REQ/mapInfo + N2.FI/REQ/mapInfo
    new_node.INT = N1.INT + N2.INT - 2
    remove N1, N2, and link between N1, N2 from vtopPart
    replace N1 or N2 with new_node in all link.EndNodes
    for any pair of links (L1, L2) in vtopPart:
          if L1.delay == L2.delay and L1.endNodes == L2.endNodes:
                newLink.endNodes = L1.endNodes;
                newlink.BW/mapInfo = L1.BW/mapInfo + L2.BW/mapInfo
                remove L1, L2 from vtopPart
vtopOut = vtopIn
replace partial records in vtopOut with records in vtopPart
add the file path to vtopOut in log